﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace d1Project.Tools.JsonParse
{
    public enum doConfigValueType { Boolean, TextValue, IntegerValue, FloatValue, NodeValue, ArrayValue }
    public class doJsonValue
    {
        public doJsonValue()
        {
            this.ValueType = doConfigValueType.TextValue;
        }

        public doConfigValueType ValueType
        {
            get;
            private set;
        }
        public string NodeName
        {
            get;
            set;
        }
        private bool BooleanValue;
        private string TextValue;
        private int IntegerValue;
        private double FloatValue;
        private doJsonNode NodeValue;
        private List<doJsonValue> ArrayValue;

        public void LoadDataFromText(string _text)
        {
            if (_text == null || _text.Trim().Length <= 0) return;
            JsonTextReader _jsonReader = new JsonTextReader(new StringReader(_text));
            this.LoadDataFromeStream(_jsonReader, false);
        }
        public void LoadDataFromeStream(JsonTextReader _reader, bool _firstFinished)
        {
            bool _allFinished = false;
            while (!_allFinished && _reader != null)
            {
                if (!_firstFinished)
                {
                    _firstFinished = false;
                    if (!_reader.Read()) break;
                }
                switch (_reader.TokenType)
                {
                    case JsonToken.StartObject:
                        doJsonNode _ondNode = new doJsonNode();
                        _ondNode.LoadDataFromStream(_reader);
                        this.SetNode(_ondNode);
                        _allFinished = true;
                        break;
                    case JsonToken.StartArray:
                        List<doJsonValue> _listConfigValues = new List<doJsonValue>();
                        bool _arraySucceedFinished = false;
                        while (!_arraySucceedFinished && _reader.Read())
                        {
                            switch (_reader.TokenType)
                            {
                                case JsonToken.EndArray:
                                    _arraySucceedFinished = true;
                                    break;
                                default:
                                    doJsonValue _childConfigValue = new doJsonValue();
                                    _childConfigValue.LoadDataFromeStream(_reader, true);
                                    _listConfigValues.Add(_childConfigValue);
                                    break;
                            }
                        }
                        if (!_arraySucceedFinished)
                        {
                            throw new Exception("配置文件的格式不正确，期待JsonToken.StartArray遭遇意外结束");
                        }
                        this.SetArray(_listConfigValues);
                        _allFinished = true;
                        break;
                    case JsonToken.Integer:
                        this.SetInteger((int)((long)_reader.Value));
                        _allFinished = true;
                        break;
                    case JsonToken.Float:
                        this.SetFloat((double)_reader.Value);
                        _allFinished = true;
                        break;
                    case JsonToken.Boolean:
                        this.SetBoolean((Boolean)_reader.Value);
                        _allFinished = true;
                        break;
                    case JsonToken.String:
                        string _value = _reader.Value == null ? "" : _reader.Value.ToString();
                        this.SetText(_value);
                        _allFinished = true;
                        break;
                    case JsonToken.Date:
                        string _value1 = _reader.Value == null ? "" : _reader.Value.ToString();
                        this.SetText(_value1);
                        _allFinished = true;
                        break;
                    case JsonToken.Bytes:
                        throw new JsonSerializationException("配置文件的格式不正确,json中存在不支持的类型JsonToken.Bytes");
                    case JsonToken.Comment:
                        break;
                    default:
                        this.SetText("");
                        _allFinished = true;
                        break;
                }
            }
            if (!_allFinished) throw new JsonSerializationException("配置文件的格式不正确,json中的数据遭遇意外的结束");
        }

        public void SetBoolean(bool _value)
        {
            this.ValueType = doConfigValueType.Boolean;
            this.BooleanValue = _value;
        }
        public void SetText(string _value)
        {
            this.ValueType = doConfigValueType.TextValue;
            this.TextValue = _value;
        }
        public void SetInteger(int _value)
        {
            this.ValueType = doConfigValueType.IntegerValue;
            this.IntegerValue = _value;
        }
        public void SetFloat(double _value)
        {
            this.ValueType = doConfigValueType.FloatValue;
            this.FloatValue = _value;
        }
        public void SetNode(doJsonNode _value)
        {
            this.ValueType = doConfigValueType.NodeValue;
            this.NodeValue = _value;
        }
        public void SetArray(List<doJsonValue> _values)
        {
            this.ValueType = doConfigValueType.ArrayValue;
            this.ArrayValue = _values;
        }
        public void SetNodeArray(List<doJsonNode> _values)
        {
            List<doJsonValue> _newVals = new List<doJsonValue>();
            foreach (doJsonNode _val in _values)
            {
                doJsonValue _newconfig = new doJsonValue();
                _newconfig.SetNode(_val);
                _newVals.Add(_newconfig);
            }
            this.SetArray(_newVals);
        }
        public void SetTextArray(List<string> _values)
        {
            List<doJsonValue> _newVals = new List<doJsonValue>();
            foreach (string _val in _values)
            {
                doJsonValue _newconfig = new doJsonValue();
                _newconfig.SetText(_val);
                _newVals.Add(_newconfig);
            }
            this.SetArray(_newVals);
        }
        public string ExportToText(bool _indented)
        {
            StringBuilder _sb = new StringBuilder();
            StringWriter _sw = new StringWriter(_sb);
            JsonTextWriter _jsonWriter = new JsonTextWriter(_sw);
            if (_indented)
            {
                _jsonWriter.Formatting = Formatting.Indented;
                _jsonWriter.Indentation = 4;
            }
            this.ExportToStream(_jsonWriter);
            return _sw.ToString();
        }
        public void ExportToStream(JsonTextWriter _jsonWriter)
        {
            if (this.ValueType == doConfigValueType.Boolean)
            {
                //受IOS的json处理能力的限制，所有输出的bool值，都统一采用0和1表示
                _jsonWriter.WriteValue(this.BooleanValue ? true : false);
                return;
            }
            if (this.ValueType == doConfigValueType.TextValue)
            {
                _jsonWriter.WriteValue(this.TextValue == null ? "" : this.TextValue);
                return;
            }
            if (this.ValueType == doConfigValueType.IntegerValue)
            {
                _jsonWriter.WriteValue(this.IntegerValue);
                return;
            }
            if (this.ValueType == doConfigValueType.FloatValue)
            {
                _jsonWriter.WriteValue(this.FloatValue);
                return;
            }
            if (this.ValueType == doConfigValueType.NodeValue)
            {
                if (this.NodeValue != null)
                {
                    this.NodeValue.ExportToStream(_jsonWriter);
                    return;
                }
                _jsonWriter.WriteStartObject();
                _jsonWriter.WriteEndObject();
                return;
            }
            if (this.ValueType == doConfigValueType.ArrayValue)
            {
                _jsonWriter.WriteStartArray();
                if (this.ArrayValue != null)
                {
                    foreach (doJsonValue _configValue in this.ArrayValue)
                    {
                        _configValue.ExportToStream(_jsonWriter);
                    }
                }
                _jsonWriter.WriteEndArray();
                return;
            }
            throw new Exception("无效的ValueType节点类型：" + this.ValueType);
        }
        public string GetText(string _defaultValue)
        {
            if (this.ValueType == doConfigValueType.Boolean)
            {
                return this.BooleanValue ? "true" : "false";
            }
            if (this.ValueType == doConfigValueType.TextValue)
            {
                return this.TextValue == null ? _defaultValue : this.TextValue;
            }
            if (this.ValueType == doConfigValueType.IntegerValue)
            {
                return this.IntegerValue.ToString();
            }
            if (this.ValueType == doConfigValueType.FloatValue)
            {
                return this.FloatValue.ToString();
            }
            if (this.ValueType == doConfigValueType.NodeValue)
            {
                return this.NodeValue == null ? _defaultValue : this.ExportToText(false);
            }
            if (this.ValueType == doConfigValueType.ArrayValue)
            {
                if (this.ArrayValue == null) return _defaultValue;
                StringBuilder _strB = new StringBuilder();
                _strB.Append("[");
                int index = 0;
                foreach (doJsonValue _configValue in this.ArrayValue)
                {
                    if (index > 0)
                    {
                        if (_strB.Length > 0) _strB.Append(",");
                    }
                    _strB.Append(_configValue.GetText(""));
                    index++;
                }
                _strB.Append("]");
                return _strB.ToString();
            }
            return _defaultValue;
        }
        public bool GetBoolean(bool _defaultValue)
        {
            if (this.ValueType == doConfigValueType.Boolean)
            {
                return this.BooleanValue;
            }
            if (this.ValueType == doConfigValueType.TextValue)
            {
                return this.TextValue == null ? _defaultValue : this.TextValue.Equals("true") ? true : _defaultValue;
            }
            if (this.ValueType == doConfigValueType.IntegerValue)
            {
                return this.IntegerValue == 0 ? false : true;
            }
            if (this.ValueType == doConfigValueType.FloatValue)
            {
                return this.FloatValue == 0 ? false : true;
            }
            if (this.ValueType == doConfigValueType.NodeValue)
            {
                return _defaultValue;
            }
            if (this.ValueType == doConfigValueType.ArrayValue)
            {
                return _defaultValue;
            }
            return _defaultValue;
        }
        public int GetInteger(int _defaultValue)
        {
            if (this.ValueType == doConfigValueType.Boolean)
            {
                return this.BooleanValue ? 1 : 0;
            }
            if (this.ValueType == doConfigValueType.TextValue)
            {
                return this.TextValue == null ? _defaultValue : TextHelper.StrToInt(this.TextValue, _defaultValue);
            }
            if (this.ValueType == doConfigValueType.IntegerValue)
            {
                return this.IntegerValue;
            }
            if (this.ValueType == doConfigValueType.FloatValue)
            {
                return (int)this.FloatValue;
            }
            if (this.ValueType == doConfigValueType.NodeValue)
            {
                return _defaultValue;
            }
            if (this.ValueType == doConfigValueType.ArrayValue)
            {
                return _defaultValue;
            }
            return _defaultValue;
        }

        public double GetFloat(double _defaultValue)
        {
            if (this.ValueType == doConfigValueType.Boolean)
            {
                return this.BooleanValue ? 1 : 0;
            }
            if (this.ValueType == doConfigValueType.TextValue)
            {
                return this.TextValue == null ? _defaultValue : TextHelper.StrToDouble(this.TextValue, _defaultValue);
            }
            if (this.ValueType == doConfigValueType.IntegerValue)
            {
                return this.IntegerValue;
            }
            if (this.ValueType == doConfigValueType.FloatValue)
            {
                return this.FloatValue;
            }
            if (this.ValueType == doConfigValueType.NodeValue)
            {
                return _defaultValue;
            }
            if (this.ValueType == doConfigValueType.ArrayValue)
            {
                return _defaultValue;
            }
            throw new Exception("无效的ValueType节点类型：" + this.ValueType);
        }
        public doJsonNode GetNode()
        {
            if (this.ValueType == doConfigValueType.NodeValue)
            {
                return this.NodeValue;
            }
            return null;
        }
        public List<doJsonValue> GetArray()
        {
            if (this.ValueType == doConfigValueType.ArrayValue)
            {
                return this.ArrayValue;
            }
            return null;
        }
    }
}